﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Socket clientSocket;
        private Socket _serverSocket = null;
        private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
        private Task _listenTask = null;

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string ip = IpTextBox.Text;
                string port = portTextBox.Text;

                if (button1.Text == "关闭服务器")
                {
                    // 停止服务器  
                    StopServer();
                }
                else
                {
                    // 启动服务器  
                    StartServer(ip, port);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"服务器操作错误：{ex.Message}");
            }
        }

        private void StartServer(string ip, string port)
        {
            // 参数验证  
            if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(port))
            {
                throw new ArgumentException("IP地址和端口不能为空");
            }

            // 重置取消令牌  
            _cancellationTokenSource = new CancellationTokenSource();

            // 创建服务器Socket  
            _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            // 绑定并监听  
            IPAddress ipAddress = IPAddress.Parse(ip.Trim());
            IPEndPoint endPoint = new IPEndPoint(ipAddress, Convert.ToInt32(port));
            _serverSocket.Bind(endPoint);
            _serverSocket.Listen(10);

            // 启动监听任务  
            _listenTask = Task.Run(() => ListenForClients(_cancellationTokenSource.Token), _cancellationTokenSource.Token);

            // 更新UI  
            button1.Text = "关闭服务器";
            MessageShowTextBox.AppendText($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]服务器已启动\r\n");
        }

        private void ListenForClients(CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    // 接受客户端连接  
                    clientSocket = _serverSocket.Accept();

                    // 处理客户端消息  
                    Task.Run(() => HandleClient(clientSocket, cancellationToken));
                }
            }
            catch (SocketException) when (cancellationToken.IsCancellationRequested)
            {
                // 正常取消，不需要额外处理  
            }
            catch (Exception ex)
            {
                // 记录异常  
                MessageBox.Show($"监听异常：{ex.Message}");
            }
        }

        private void HandleClient(Socket clientSocket, CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested && clientSocket.Connected)
                {
                    byte[] buffer = new byte[1024];
                    int received = clientSocket.Receive(buffer);
                    string message = Encoding.Default.GetString(buffer, 0, received);

                    // 使用线程安全的方式更新UI  
                    this.Invoke(new Action(() =>
                    {
                        MessageShowTextBox.AppendText($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]接收到客户端消息：{message}\r\n");
                    }));

                    if (message == "close")
                    {
                        break;
                    }
                }
            }
            catch (Exception)
            {
                // 处理客户端连接异常  
            }
            finally
            {
                clientSocket?.Close();
            }
        }

        private void StopServer()
        {
            try
            {
                clientSocket.Send(Encoding.Default.GetBytes("close"));
                // 取消监听任务  
                _cancellationTokenSource.Cancel();

                // 关闭服务器Socket  
                _serverSocket?.Close();
                _serverSocket = null;

                // 等待监听任务结束  
                _listenTask?.Wait(1000);

                // 重置UI  
                button1.Text = "启动服务器";
                MessageShowTextBox.AppendText($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]服务器已关闭\r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"关闭服务器时发生错误：{ex.Message}");
            }
        }
    }
}